package com.chenfan.mcn.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.chenfan.common.exception.BusinessException;
import com.chenfan.mcn.clients.baseinfo.BaseInfoClient;
import com.chenfan.mcn.clients.baseinfo.DescByCodeDTO;
import com.chenfan.mcn.config.UserVoContextHolder;
import com.chenfan.mcn.constant.BillCodeCst;
import com.chenfan.mcn.constant.NumberCst;
import com.chenfan.mcn.constant.SeparatorCst;
import com.chenfan.mcn.dao.LiveContractCommodityMapper;
import com.chenfan.mcn.dao.LiveSessionMapper;
import com.chenfan.mcn.dao.StarBasicDataMapper;
import com.chenfan.mcn.dao.StarPlatformInfoMapper;
import com.chenfan.mcn.exception.McnErrorCode;
import com.chenfan.common.extension.dict.DictStream;
import com.chenfan.common.extension.dict.DictTranslationUtils;
import com.chenfan.mcn.component.CodeGenerateHelper;
import com.chenfan.mcn.model.LiveContractCommodity;
import com.chenfan.mcn.model.LiveSession;
import com.chenfan.mcn.model.StarPlatformInfo;
import com.chenfan.mcn.model.dto.LiveSessionSaveDTO;
import com.chenfan.mcn.model.dto.LiveSessionSearchDTO;
import com.chenfan.mcn.model.vo.LiveSessionDetailVO;
import com.chenfan.mcn.model.vo.LiveSessionListExportVO;
import com.chenfan.mcn.model.vo.LiveSessionListVO;
import com.chenfan.mcn.service.LiveSessionService;
import com.chenfan.mcn.utils.BusinessAssert;
import com.chenfan.mcn.utils.CommonUtil;
import com.chenfan.mcn.utils.DateUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author: WQ
 * Date 2023/4/27
 * @描述
 */
@Service
public class LiveSessionServiceImpl implements LiveSessionService {

    @Autowired
    private LiveSessionMapper liveSessionMapper;

    @Autowired
    private LiveContractCommodityMapper liveContractCommodityMapper;

    @Autowired
    private StarPlatformInfoMapper starPlatformInfoMapper;

    @Autowired
    private StarBasicDataMapper basicDataMapper;

    @Autowired
    private BaseInfoClient baseInfoClient;


    @Override
    public Long save(LiveSessionSaveDTO liveSessionAddDTO) {
        LiveSession liveSession = new LiveSession();
        BeanUtils.copyProperties(liveSessionAddDTO, liveSession);
        if (liveSession.getId() == null) {
            liveSession.setLiveDate(liveSessionAddDTO.getLiveDate());
            liveSession.setLsCode(CodeGenerateHelper.getCode(BillCodeCst.ZBPQ));
            liveSessionMapper.insert(liveSession);
        } else {
            LiveSession entity = liveSessionMapper.selectById(liveSession.getId());
            BusinessAssert.notNull(entity, McnErrorCode.DATA_NOT_FOUND, "无该直播场次");
            String sourceAnchor = StringUtils.joinWith(SeparatorCst.MINUS, entity.getStarId(), entity.getStarPlatId());
            String targetAnchor = StringUtils.joinWith(SeparatorCst.MINUS, liveSessionAddDTO.getStarId(), liveSessionAddDTO.getStarPlatId());
            if(!sourceAnchor.equals(targetAnchor)) {
                BusinessAssert.isFalse(liveContractCommodityMapper.exist(Wrappers.lambdaQuery(LiveContractCommodity.class)
                        .eq(LiveContractCommodity::getLsId, liveSession.getId())
                        .eq(LiveContractCommodity::getIsDelete, NumberCst.ZERO).ne(LiveContractCommodity::getSettlementStatus, NumberCst.THREE)
                ), McnErrorCode.BUSINESS_ERROR, "该场次商品已经进入结算，不允许修改主播！");
            }
            liveSession.setLiveDate(liveSessionAddDTO.getLiveDate());
            liveSessionMapper.updateById(liveSession);
        }
        return liveSession.getId();
    }

    @Override
    public Boolean invalid(Long lsId) {
        List<LiveContractCommodity> list = liveContractCommodityMapper.selectList(new LambdaQueryWrapper<LiveContractCommodity>()
                .eq(LiveContractCommodity::getLsId, lsId).eq(LiveContractCommodity::getIsDelete, NumberCst.ZERO));
        if (CollectionUtils.isNotEmpty(list)) {
            throw new BusinessException(McnErrorCode.DELETE_ERROR_HAVE_COMMODITY);
        }
        LiveSession liveSession = new LiveSession();
        liveSession.setId(lsId);
        liveSession.setStatus(NumberCst.ONE);
        liveSessionMapper.updateById(liveSession);
        return true;
    }

    @Override
    public LiveSessionListVO list(LiveSessionSearchDTO searchDTO) {
        LiveSessionListVO liveSessionListVO = new LiveSessionListVO();
        LambdaQueryWrapper<LiveSession> queryWrapper = new LambdaQueryWrapper<LiveSession>()
                .eq(searchDTO.getStarId() != null, LiveSession::getStarId, searchDTO.getStarId())
                .eq(searchDTO.getStatus() != null, LiveSession::getStatus, searchDTO.getStatus())
                .eq(LiveSession::getTenantId, UserVoContextHolder.defaultTenantId())
                .in(CollectionUtils.isNotEmpty(searchDTO.getUserIds()), LiveSession::getOwnerId, searchDTO.getUserIds())
                .in(CollectionUtils.isNotEmpty(searchDTO.getCompanyIds()), LiveSession::getCompanyId, searchDTO.getCompanyIds())
                .between(searchDTO.getLiveMonth() != null, LiveSession::getLiveDate, DateUtil.getMonthFirstDay(searchDTO.getLiveMonth()), DateUtil.getMonthLastDay(searchDTO.getLiveMonth()));
        List<LiveSession> list = liveSessionMapper.selectList(queryWrapper);
        List<Date> dayList = DateUtil.getAllDayOfMonth(searchDTO.getLiveMonth());
        List<LiveSessionListVO.DayMapLivesVO> dayMapLivesVOList = new ArrayList<>();
        if (CollectionUtils.isEmpty(list)) {
            dayList.forEach(key -> {
                LiveSessionListVO.DayMapLivesVO dayMapLivesVO = new LiveSessionListVO.DayMapLivesVO();
                dayMapLivesVO.setLiveDay(key);
                dayMapLivesVO.setLiveSessionVOS(Collections.EMPTY_LIST);
                dayMapLivesVOList.add(dayMapLivesVO);
            });
            liveSessionListVO.setDayMapLivesVOS(dayMapLivesVOList);
            liveSessionListVO.setLiveGMV(BigDecimal.ZERO);
            return liveSessionListVO;
        }
        //统计GMV
        List<Long> lsIds = list.stream().map(LiveSession::getId).collect(Collectors.toList());
        BigDecimal gmv = liveContractCommodityMapper.getGmvByLsIds(lsIds);
        liveSessionListVO.setLiveGMV(gmv);
        //获取红人平台信息
        Set<Long> starPlatIds = list.stream().filter(item -> item.getStarPlatId() != null).map(x -> x.getStarPlatId()).collect(Collectors.toSet());
        Map<Long, StarPlatformInfo> starPlatformInfoMap = CommonUtil.defaultList(starPlatformInfoMapper.selectBatchIds(starPlatIds)).stream().collect(Collectors.toMap(StarPlatformInfo::getId, Function.identity(), (x, y) -> x));
        Map<Date, List<LiveSession>> liveDateMap = list.stream().collect(Collectors.groupingBy(LiveSession::getLiveDate));
        //参考博主排期填充当月日期
        if (CollectionUtils.isNotEmpty(dayList)) {
            dayList.forEach(key -> {
                LiveSessionListVO.DayMapLivesVO dayMapLivesVO = new LiveSessionListVO.DayMapLivesVO();
                dayMapLivesVO.setLiveDay(key);
                List<LiveSession> liveSessions = liveDateMap.get(key);
                if (CollectionUtils.isNotEmpty(liveSessions)) {
                    List<LiveSessionListVO.LiveSessionVO> voList = new ArrayList<>();
                    //填充当天直播场次数据
                    liveSessions.forEach(item -> {
                        LiveSessionListVO.LiveSessionVO liveSessionVO = new LiveSessionListVO.LiveSessionVO();
                        BeanUtils.copyProperties(item, liveSessionVO);
                        StarPlatformInfo starPlatformInfo = starPlatformInfoMap.get(item.getStarPlatId());
                        if (starPlatformInfo != null) {
                            liveSessionVO.setStartPlatName(starPlatformInfo.getPlatNickName());
                        }
                        voList.add(liveSessionVO);
                    });
                    dayMapLivesVO.setLiveSessionVOS(voList);
                } else {
                    dayMapLivesVO.setLiveSessionVOS(Collections.EMPTY_LIST);
                }
                dayMapLivesVOList.add(dayMapLivesVO);
            });
        }

        liveSessionListVO.setDayMapLivesVOS(dayMapLivesVOList);
        return liveSessionListVO;
    }

    @Override
    public LiveSessionDetailVO detail(Long lsId) {
        LiveSessionDetailVO detailVO = liveSessionMapper.selectLiveSession(lsId);
        detailVO.setGmv(liveContractCommodityMapper.getGmvByLsIds(Arrays.asList(lsId)));
        return detailVO;
    }
    @Override
    public List<LiveSessionListExportVO> exportExcel(LiveSessionSearchDTO searchDTO) {
        searchDTO.setAlias("ls.");
        List<LiveSessionListExportVO> list = liveSessionMapper.exportExcel(searchDTO);
        DictTranslationUtils.translation(() -> DictStream.of(
                DictStream.map("liveContractCategory", LiveSessionListExportVO::getCommodityClass, LiveSessionListExportVO::setCommodityClassName)),
                (dictProfileList, dictList) -> Objects.requireNonNull(baseInfoClient.getDescByCode(new DescByCodeDTO().setDictsCodes(dictList.stream().distinct().collect(Collectors.toList())).setProfileCodes(dictProfileList))).getObj(), list);
        return CommonUtil.defaultList(list);
    }
}
